package baidu

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"strings"
	"time"
	zimgio "wisdom_education_in_kunshan/image"
	"wisdom_education_in_kunshan/ocr"
	"wisdom_education_in_kunshan/znet"
)

type baidu uint8

var bdLock chan int

func init() {
	bdLock = make(chan int, 1)
	bdLock <- 1
	ocr.DefaultOCR = baidu(0)
}

type baiduRespJSON struct {
	Errno int              `json:"errno"`
	Msg   string           `json:"msg"`
	Data  baiduOCRRespJSON `json:"data"`
}

type baiduOCRRespJSON struct {
	LogID          string            `json:"log_id"`
	Direction      int               `json:"direction"`
	WordsResultNum int               `json:"words_result_num"`
	WordsResult    []baiduWordResult `json:"words_result"`
}

type baiduWordResult struct {
	Words string `json:"words"`
}

func (baidu) OCR(args ...string) (string, bool) {
	<-bdLock
	defer func() {
		time.Sleep(2 * time.Second)
		bdLock <- 1
	}()

	if len(args) == 0 {
		log.Println("Need image src as arg", args)
		return Null, false
	}
	base64, err := zimgio.Base64(args[0])
	if err != nil {
		log.Println("Base64 Image err!", base64, err)
		return Null, false
	}
	data := url.QueryEscape(fmt.Sprintf("data:image/png;base64,%s", base64))
	body := strings.NewReader(fmt.Sprintf("type=commontext&image=%s&image_url=", data))

	httpClient := znet.NewClient()
	jar, err := cookiejar.New(nil)
	if err != nil {
		log.Println("Init OCR err", err)
		return Null, false
	}
	httpClient.Jar = jar
	znet.Get(httpClient, "http://ai.baidu.com/tech/ocr/general")

	req, _ := http.NewRequest("POST", "https://cloud.baidu.com/aidemo", body)
	req.Header.Add("Accept", "*/*")
	req.Header.Add("Accept-Encoding", "gzip, deflate, br")
	req.Header.Add("Accept-Language", "zh-CN,zh;q=0.8")
	req.Header.Add("Connection", "keep-alive")
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
	req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36")
	req.Header.Add("Referer", "https://cloud.baidu.com/product/ocr/general")
	req.Header.Add("X-Requested-With", "XMLHttpRequest")
	if len(args) > 1 {
		req.Header.Add("Cookie", args[1])
	}

	res, err := httpClient.Do(req)
	if err != nil {
		log.Println("POST https://cloud.baidu.com/aidemo", err)
		return Null, true
	}
	defer res.Body.Close()
	if res.StatusCode == http.StatusOK {
		baiduOCRJson := &baiduRespJSON{}
		err = json.NewDecoder(res.Body).Decode(baiduOCRJson)
		if err != nil {
			log.Println("baidu ocr err!", err)
			return Null, false
		}

		if baiduOCRJson.Errno != 0 || len(baiduOCRJson.Data.WordsResult) == 0 {
			log.Println("baidu ocr result:", baiduOCRJson)
			return Null, false
		}
		return baiduOCRJson.Data.WordsResult[0].Words, true
	} else {
		log.Println("baidu ocr request err", res.StatusCode, res.Status)
		return res.Status, false
	}
}
